﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Threading;
using Rabbit.BusinessLogicLayer;
using Rabbit.Model;
using Rabbit.Utils;

namespace MicroBlogClient
{
    /// <summary>
    /// Interaction logic for Letters.xaml
    /// </summary>
    public partial class Letters : PageBase
    {
        #region Observable Collections
        ObservableCollection<Letter> InBoxLettersCollection = new ObservableCollection<Letter>();
        ObservableCollection<Letter> OutBoxLettersCollection = new ObservableCollection<Letter>();
        #endregion

        List<Letter> InBoxLettersPool = new List<Letter>();

        public static LettersBL letterBL;
        public long SendToUserID; 
        public Letters()
        {
            InitializeComponent();
            lstInBox.ItemsSource = InBoxLettersCollection;
            lstOutBox.ItemsSource = OutBoxLettersCollection;
            this.Loaded += new RoutedEventHandler(Letters_Loaded);
        }

        public override void StartLoading()
        {  
            base.StartLoading();

            letterBL = new LettersBL(MySettings.UpdateInterval.Value);
            letterBL.OnUnknownExceptionOccured = base.OnUnHandledExceptionOccured;

            letterBL.OnMessageInitialized = InBoxLettersInitialized;
            letterBL.OnNewMessageReceived = NewLetterReceived;
            letterBL.OnPublishAPICallTooFrequent = base.OnCallAPITooFrequentExceptionOccured;
            BeginInitializeMessage();
        }
        void InBoxLettersInitialized(List<Letter> letterList)
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                letterList.ForEach(letter => InBoxLettersCollection.Add(letter));
            }), DispatcherPriority.Background); 
        }

        void NewLetterReceived(List<Letter> newLetterList)
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
            { 
                List<Letter> removedLetter;
                //call new letter received method, to flush current letter to 
                (App.Current.MainWindow as MainWindow).NewLetterReceived(newLetterList, out removedLetter);
                removedLetter.ForEach(l=>InBoxLettersCollection.Insert(0,l));
                newLetterList.RemoveAll(l => removedLetter.Exists(t => t.Id == l.Id));

                if (newLetterList.Count == 0)
                {
                    return;
                }

                InBoxLettersCollection.ForEach(l => l.CreatedAt = l.CreatedAt);  //refresh the create at showed on the list
                InBoxLettersPool.InsertRange(0, newLetterList);

                MessagePoolCount += newLetterList.Count;

                if (InBoxLettersPool.Count > MaxRecordsCountShowed)
                {
                    InBoxLettersPool.RemoveRange(MaxRecordsCountShowed, InBoxLettersPool.Count - MaxRecordsCountShowed);
                }
                TryPopupMessage<Letter>(MySettings.PopupForNewLetter,
                    new Action<object, MouseButtonEventArgs>((o, args) =>
                    {
                        this.Dispatcher.BeginInvoke((Action)delegate()
                        {
                            (App.Current.MainWindow as MainWindow).FlushMyLetterPool(o, args);
                        });
                    }), 
                    "私信",
                    newLetterList[0]);
            }), DispatcherPriority.Background);
        }
        void Letters_Loaded(object sender, RoutedEventArgs e)
        {
            txtLetterContent.Focus();
        }

        void fetchingOutBox()
        {
            Action fetching = () =>
                          {
                              List<Letter> tempLetterList = letterBL.GetMySentLetters();
                              this.Dispatcher.BeginInvoke(new Action(() =>
                              {
                                  tempLetterList.ForEach(letter => OutBoxLettersCollection.Add(letter));
                              }), DispatcherPriority.Background);
                          };
            fetching.BeginInvoke(null, null);
        }
         
        private void DeleteInBoxLetter(object sender, RoutedEventArgs e)
        {
            try
            {
                long letterID = (long)(sender as Hyperlink).CommandParameter;
                letterBL.DeleteInBoxLetter(letterID);
                InBoxLettersCollection.Remove(l => l.Id == letterID);
                base.ShowSuccessfulMessage("删除成功");
            }
            catch (MaxRatesExceededException ex)
            {
                base.ShowFailedMessage(ex);
            }
            catch
            {
                base.ShowFailedMessage("删除失败,请重试");
            }
        }

        private void DeleteOutBoxLetter(object sender, RoutedEventArgs e)
        {
            try
            {
                long letterID = (long)(sender as Hyperlink).CommandParameter;
                letterBL.DeleteOutBoxLetter(letterID);
                OutBoxLettersCollection.Remove(l => l.Id == letterID);
                base.ShowSuccessfulMessage("删除成功");
            }
            catch (MaxRatesExceededException ex)
            {
                base.ShowFailedMessage(ex);
            }
            catch
            { 
                base.ShowFailedMessage("删除失败,请重试");
            }
        }
     
        private void ReplyLetter_Click(object sender, RoutedEventArgs e)
        {
            ListBoxItem item = Common.GetListBoxItemFromChild((sender as Hyperlink).Parent);
            Letter letter = item.Content as Letter;
            SendToUserID = letter.SenderId;
            txtSendTo.Text = letter.SenderScreenName;
            gridReplyLetter.Visibility = System.Windows.Visibility.Visible;
            txtLetterContent.Focus();
        }


        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            gridReplyLetter.Visibility = System.Windows.Visibility.Collapsed;
            txtLetterContent.Text = "";
            SendToUserID = 0;
        }

        private void btnSend_Click(object sender, RoutedEventArgs e)
        {
            
                string message = txtLetterContent.Text.Trim();
                if (string.IsNullOrEmpty(message))
                {
                    base.ShowFailedMessage("私信内容不要为空哦");
                    txtLetterContent.Focus();
                    return;
                }

                base.ShowProcessingMessage("正在发送私信...");
                Action action = new Action(() =>
                    {
                        try
                        {
                            Letter returnedLetter = letterBL.SendLetter(SendToUserID, message);
                            this.Dispatcher.BeginInvoke(new Action(() =>
                            {
                                OutBoxLettersCollection.Insert(0, returnedLetter);
                                gridReplyLetter.Visibility = Visibility.Collapsed;
                                txtLetterContent.Text = "";
                                base.ShowSuccessfulMessage("发送成功");
                            }));
                        }
                        catch (MaxRatesExceededException ex)
                        {
                            base.ShowFailedMessage(ex);
                        }
                        catch (Exception ex)
                        {
                            LogHelper.LogError(ex);
                            base.ShowFailedMessage("发送失败,请重试");
                        }
                    });
                action.BeginInvoke(null, null);
        }
       
        private void txtLetterContent_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            //if Ctrl+Enter pressed,call btnPublishStatus_click to publish the status
            if (e.KeyStates == Keyboard.GetKeyStates(Key.Enter)
               && Keyboard.Modifiers == ModifierKeys.Control
               )
            {
                btnSend_Click(null, null);
            }
        }

        protected override void NotifyMainWindowNewMessageCountChanged(int messageCount)
        {
            (App.Current.MainWindow as MainWindow).NewLetterCount = messageCount;
        }

        public override void DoWork(object obj = null)
        {
            tabLettersContent.SelectedItem = tabItemInBox;
            if (obj == null)
            {
                if (InBoxLettersPool.Count == 0)
                {
                    return;
                }
                App.StopTwinkleSysTrayIcon();

                InBoxLettersCollection.InsertRange(InBoxLettersPool, MaxRecordsCountShowed);
                lstInBox.ScrollIntoView(InBoxLettersCollection[0]);
                InBoxLettersPool.Clear();
                NotifyMainWindowNewMessageCountChanged(0);
                MessagePoolCount = 0;
            }
            else if (obj.GetType() == typeof(User))
            {
                //send letter to a user
                User tempUser = obj as User;
                txtSendTo.Text = tempUser.ScreenName;
                SendToUserID = tempUser.Id;
                gridReplyLetter.Visibility = System.Windows.Visibility.Visible;
            }
        }

        public override void BeginInitializeMessage()
        {
            letterBL.StartFetchingMessage();
            fetchingOutBox();
        }

        public override void pager_OnFirstPageClick(object sender, RoutedEventArgs e)
        {
            ShowProcessingMessage("正在加载...");
            Action fetching = () =>
            {
                try
                {
                    List<Letter> fetchedMessage = letterBL.GetFirstPageMessage();
                    this.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        InBoxLettersCollection.Clear();
                        fetchedMessage.ForEach(c => InBoxLettersCollection.Add(c));
                        pager.CanPreviousePageClick = false;
                        pager.CanNextPageClick = letterBL.CanGetNextPage;

                        if (InBoxLettersCollection.Count > 0)
                        {
                            lstInBox.ScrollIntoView(InBoxLettersCollection[0]);
                        }
                    }));
                    base.HideMessage();
                }
                catch (Exception ex)
                {
                    ShowFailedMessage("获取失败:" + ex.Message);
                }
            };

            fetching.BeginInvoke(null, null);
        }

        public override void pager_OnPreviousePage(object sender, RoutedEventArgs e)
        {
            ShowProcessingMessage("正在加载...");
            Action fetching = () =>
            {
                try
                {
                    List<Letter> fetchedMessage = letterBL.GetPreviousePageMessage();
                    this.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        InBoxLettersCollection.Clear();
                        fetchedMessage.ForEach(c => InBoxLettersCollection.Add(c));
                        pager.CanPreviousePageClick = letterBL.CanGetPreviousePage;
                        pager.CanNextPageClick = letterBL.CanGetNextPage;
                        if (InBoxLettersCollection.Count > 0)
                        {
                            lstInBox.ScrollIntoView(InBoxLettersCollection[0]);
                        }
                    }));
                    base.HideMessage();
                    //ShowSuccessfulMessage("加载完成");
                }
                catch (Exception ex)
                {
                    ShowFailedMessage("获取失败:" + ex.Message);
                }
            };

            fetching.BeginInvoke(null, null);
        }

        public override void pager_OnNextPageClick(object sender, RoutedEventArgs e)
        {
            ShowProcessingMessage("正在加载...");
            Action fetching = () =>
            {
                try
                {
                    List<Letter> fetchedMessage = letterBL.GetNextPageMessage();
                    this.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        InBoxLettersCollection.Clear();
                        fetchedMessage.ForEach(c => InBoxLettersCollection.Add(c));
                        pager.CanPreviousePageClick = true;
                        pager.CanNextPageClick = letterBL.CanGetNextPage;
                        if (InBoxLettersCollection.Count > 0)
                        {
                            lstInBox.ScrollIntoView(InBoxLettersCollection[0]);
                        }
                    }));
                    base.HideMessage();
                }
                catch (Exception ex)
                {
                    ShowFailedMessage("获取失败:" + ex.Message);
                }
            };

            fetching.BeginInvoke(null, null);
        }

        public override void StopFetchingMessage()
        {
            if (letterBL != null)
            {
                letterBL.StopFetchingMessage();
                letterBL = null;
            }

            InBoxLettersCollection.Clear();
            OutBoxLettersCollection.Clear();
        }

        private void OpenChatWindow(object sender, RoutedEventArgs e)
        {
            User user = (sender as Hyperlink).CommandParameter as User;
            (App.Current.MainWindow as MainWindow).OpenChatWindow(user,false);
        }
    }
}
